home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
MATHEMAT
/
2632.ZIP
/
MERCURYZ.EXE
/
X0.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-24
|
3KB
|
133 lines
/* X0.c
This is the startup module for external functions.
Recompiling requires Borland C++ or Turbo C and Assembler.
There is an alternate startup module in this file for external
functions which do not require DS=SS. The math library, ld.lib,
which has been provided, does not require DS=SS. Programs built
with this save some disk space.
Options.
You must set Opt=1 or Opt=2.
1. External function sets up its own stack segment. This allows
you to guarantee enough stack space, but more importantly, it allows
DS=SS which is what the compiler expects in tiny model. Unfortunately,
however, the floating point emulator doesn't work in a foreign stack
segment. Do not use this option unless you are using a math coprocessor.
2. External function uses Mercury's stack segment. This is more efficient,
but requires you to write your function in tiny model without using DS=SS,
which Borland C tiny model normally assumes. Most simple functions in tiny
model don't actually make use of DS=SS, but this option is dangerous unless
you are familiar with the way Turbo C generates code.
bcc -c -mt! -w -ox01 -DOpt=1 -Z -O x0
bcc -c -mt! -w -ox02 -DOpt=2 -Z -O x0
x01.obj uses stack swap
x02.obj uses Mercury stack
See the examples, GCD.C and ASINH.C, for instructions on how to link.
Using Option 1 requires linking with F87.OBJ.
If using Turbo, compile with "tcc -c -mt -w ...".
*/
#pragma inline
/* TC is not too happy about this, but it does the right thing. */
#pragma warn -asm
asm DGROUP group _TEXT,_DATA,_BSS
#pragma warn .asm
pascal xmain(double far *);
/*
To handle tiny model properly, must have CS=DS=SS.
Simple programs, eg not passing addresses of local variables, don't need SS.
*/
#ifndef Opt
#error Must define Opt=1 or Opt=2.
#endif
#if Opt == 1
#define SwapSS 1
#endif
#if Opt == 2
#define SwapSS 0
#endif
#if !SwapSS
/* Opt = 2 */
static void far pascal start(double *a)
{
_ES = _SI = _DS;
_DS = _CS;
xmain((double _es *) a);
_DS = _SI;
return;
}
#else
/* Opt = 1 */
/* make external, so user can set it? */
#define StackWords 1000
int stack[StackWords] = { 0 };
/*
Must preserve bp, si, di, ds, ss.
Called with ds = ss.
*/
static void far pascal start(double *a)
{
_BX = (unsigned int) a;
asm mov cx, sp
asm mov dx, ss
_AX = (unsigned int) (&stack[StackWords]);
/* switch to local stack */
asm push cs
asm pop ss
asm mov sp, ax
/* save prior ss, sp */
asm push dx
asm push cx
/* set ds=cs */
asm push cs
asm pop ds
/* call xmain */
asm mov es, dx
xmain((double _es *) _BX);
/* restore ss, sp, ds=ss */
asm pop cx
asm pop dx
asm mov ss, dx
asm mov sp, cx
asm mov ds, dx
return;
}
#endif